package com.ft.controller;

import com.ft.config.properties.WeiXinPayProperties;
import com.ft.dao.OrderStrDao;
import com.ft.dao.TixianDao;
import com.ft.dao.UserDao;
import com.ft.domain.*;
import com.ft.service.*;
import com.ft.service.impl.WxPayServiceImpl;
import com.ft.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.websocket.server.PathParam;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: ft
 * @Date: 2022/10/08/14:24
 * @Description: 微信支付接口
 */
@RestController
@RequestMapping("/wxpay")
@CrossOrigin
@Transactional
public class WeiXinPayController {
    @Autowired
    private WeiXinPayProperties weiXinPay;
    @Autowired
    private WxPayServiceImpl wxsl;
    @Autowired
    IBuyorderService buyorderService;
    @Autowired
    ISendorderService sendorderService;
    @Autowired
    IWorkorderService workorderService;
    @Autowired
    INeedService needService;
    @Autowired
    ITzmarketService tzmarketService;
    @Autowired
    private OrderStrDao orderStrDao;
    @Autowired
    private INongsukeallidService nongsukeallidService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private TixianDao tixianDao;

    /**
     * @param wxp 微信预支付订单接口
     * @return 返回唤起支付的参数
     * @throws Exception
     */
    @PostMapping()
    public Result pay(@RequestBody WeiXinPay wxp) throws Exception {
        //获取订单数据

        Map<String, String> js = new HashMap<String, String>();
        String ip = "127.0.0.1";
        js.put("appid", weiXinPay.getAppid());
        js.put("mch_id", weiXinPay.getMchid());
        //随机字符串
        js.put("nonce_str", MD5Utils.randomStr());
        /**
         * 业务数据
         */
        //订单名称
        js.put("body", wxp.getName());
        //订单号
        //封装订单号，解决订单退款后不能再次购买问题
        String orderIdStr = WxPayUtils.setOrderId(wxp.getOrderid(), 12);
        js.put("out_trade_no", orderIdStr);
        //先查询该订单是否是有退款id记录
        OrderStr orderStr1 = orderStrDao.getOrderStr(wxp.getOrderid());
        int F = 0;
        if (orderStr1 == null) {
            //首次支付的情况
            //创建退款对象
            OrderStr orderStr = new OrderStr();
            orderStr.setBelongorderid(Long.valueOf(wxp.getOrderid()));
            orderStr.setTkstrorderid(orderIdStr);
            //将退款id存入退款订单表
            F = orderStrDao.addOrderStr(orderStr);
        } else {
            F = orderStrDao.updateOrderStr(orderIdStr, wxp.getOrderid());

        }
        if(F == 0){
            return new Result(Code.POST_ERR,"生成预支付订单失败");
        }
        //订单价格
        js.put("total_fee", WxPayUtils.getMoney(wxp.getPrice()));
        //付款ip
        js.put("spbill_create_ip", ip);
        //回调地址，小程序可以不用写
        js.put("notify_url", "https://www.baidu.com");
        js.put("trade_type", weiXinPay.getType());
        js.put("openid", wxp.getOpenid());
        //签名
        String postStr = WxPayUtils.Md5Sgin(js, weiXinPay.getAppsecret());
        js.put("sign", postStr);
        //发送请求
        String str = WxPayUtils.sendPost(js);
        System.out.println("后台支付请求的结果是:" + str);
        WeiXinPayToUniapp weiXinPayToUniapp = wxsl.wxPay(weiXinPay.getGateway(), str);
        weiXinPayToUniapp.setOrderid(orderIdStr);
        return new Result(Code.GET_OK, weiXinPayToUniapp, "请求成功");
    }

    @PostMapping("/cashwithdrawal/{userid}/{money}/{oppid}")
    @Transactional(rollbackFor = {Exception.class})
    public Result cashWithdrawal(@PathVariable int userid, @PathVariable String money,@PathVariable String oppid) throws Exception {
        //先查询余额是否够
        double userMoney = userDao.getUserMoney(userid);
        BigDecimal rate = new BigDecimal(userMoney);
        BigDecimal rate2 = new BigDecimal(money);
        BigDecimal subtract = rate.subtract(rate2).setScale(2,BigDecimal.ROUND_HALF_DOWN);
        int T = subtract.intValue();
        System.out.println(T);
        if(T < 0){
            return new Result(Code.PUT_ERR,"余额不足");
        }
        System.out.println("111");
        //提现单号
        SnowFlakeGenerateIdWorker snowFlakeGenerateIdWorker =
                new SnowFlakeGenerateIdWorker(0L,0L);
        String id = snowFlakeGenerateIdWorker.generateNextId();
        //创建提现订单表
        Tixian tixianOrder = new Tixian();
        tixianOrder.setId(Long.valueOf(id));
        tixianOrder.setMoney(Double.parseDouble(money));
        int addtixian = tixianDao.addtixian(tixianOrder);
        if(addtixian == 0){
            return new Result(Code.POST_ERR,"提现失败");
        }
        //提现对象
        Map<String,String> params = new HashMap<String,String>(10);
        params.put("mch_appid", weiXinPay.getAppid());
        params.put("mchid",weiXinPay.getMchid());
        params.put("nonce_str",MD5Utils.randomStr());
        params.put("partner_trade_no",id);
        params.put("openid",oppid);
        params.put("check_name","NO_CHECK");
        params.put("amount",WxPayUtils.getMoney(money));
        params.put("desc","提现");
        String postStr = WxPayUtils.Md5Sgin(params, weiXinPay.getAppsecret());
        params.put("sign", postStr);
        //得到请求的参数
        String xmlStr = WxPayUtils.sendPost(params);
        System.out.println("请求的XML"+xmlStr);
        int wxtx = wxsl.wxtx(weiXinPay.getTxurl(), xmlStr);
        if(wxtx == 1){
            return new Result(Code.POST_OK, "提现成功");
        }
        return new Result(Code.POST_ERR, "提现失败");
    }

    /**
     * 退款接口
     *
     * @param orderid 订单号
     * @param type    订单类型
     * @return
     * @throws Exception
     */
    @PostMapping("/tk/{orderid}/{type}")
    public Result pay2(@PathVariable String orderid, @PathVariable int type) throws Exception {
        //订单信息
        Object order = new Object();
        //退款订单id
        String tkOrderId = "";
        //订单金额
        String money = "";
        //查询订单信息
        if (type == 1) {
            order = buyorderService.selectBuyOrder(Long.valueOf(orderid));
            if (order == null) {
                return new Result(Code.POST_ERR, "退款失败，订单为空");
            } else if (((Buyorder) order).getState() == 5) {
                return new Result(Code.POST_ERR, "退款失败，该订单已经退款成功");
            } else if (((Buyorder) order).getState() == 2) {
                return new Result(Code.POST_ERR, "已接单订单不能退款喔，下拉刷新下页面");
            }
            //查询退款id
            OrderStr orderStr = orderStrDao.getOrderStr(orderid);
            tkOrderId = orderStr.getTkstrorderid();
            money = String.valueOf(((Buyorder) order).getPrice());
        } else if (type == 2) {
            order = sendorderService.selectSendOrder(Long.valueOf(orderid));
            if (order == null) {
                return new Result(Code.POST_ERR, "退款失败，订单为空");
            } else if (((Sendorder) order).getState() == 5) {
                return new Result(Code.POST_ERR, "退款失败，该订单已经退款成功");
            } else if (((Sendorder) order).getState() == 2) {
                return new Result(Code.POST_ERR, "已接单订单不能退款喔，下拉刷新下页面");
            }
            //查询退款id
            OrderStr orderStr = orderStrDao.getOrderStr(orderid);
            tkOrderId = orderStr.getTkstrorderid();
            money = String.valueOf(((Sendorder) order).getPrice());
        } else if (type == 3) {
            order = workorderService.selectWorkorder(Long.valueOf(orderid));
            if (order == null) {
                return new Result(Code.POST_ERR, "退款失败，订单为空");
            } else if (((Workorder) order).getState() == 5) {
                return new Result(Code.POST_ERR, "退款失败，该订单已经退款成功");
            } else if (((Workorder) order).getState() == 2) {
                return new Result(Code.POST_ERR, "已接单订单不能退款喔，下拉刷新下页面");
            }
            //查询退款id
            OrderStr orderStr = orderStrDao.getOrderStr(orderid);
            tkOrderId = orderStr.getTkstrorderid();
            money = String.valueOf(((Workorder) order).getPrice());
        } else if (type == 4) {
            order = needService.selectNeed(Long.valueOf(orderid));
            if (order == null) {
                return new Result(Code.POST_ERR, "退款失败，订单为空");
            } else if (((Need) order).getState() == 5) {
                return new Result(Code.POST_ERR, "退款失败，该订单已经退款成功");
            } else if (((Need) order).getState() == 2) {
                return new Result(Code.POST_ERR, "已接单订单不能退款喔，下拉刷新下页面");
            }
            //查询退款id
            OrderStr orderStr = orderStrDao.getOrderStr(orderid);
            tkOrderId = orderStr.getTkstrorderid();
            money = String.valueOf(((Need) order).getPrice());
        } else if (type == 5) {
            order = tzmarketService.selectTzmarket(Long.valueOf(orderid));
            if (order == null) {
                return new Result(Code.POST_ERR, "退款失败，订单为空");
            } else if (((Tzmarket) order).getState() == 5) {
                return new Result(Code.POST_ERR, "退款失败，该订单已经退款成功");
            }
            //查询退款id
            OrderStr orderStr = orderStrDao.getOrderStr(orderid);
            tkOrderId = orderStr.getTkstrorderid();
            money = String.valueOf(((Tzmarket) order).getPrice());
        } else if (type == 6) {
            order = nongsukeallidService.getOrder(Long.valueOf(orderid));
            if (order == null) {
                return new Result(Code.POST_ERR, "退款失败，订单为空");
            } else if (((Nongsukeallid) order).getState() == 5) {
                return new Result(Code.POST_ERR, "退款失败，该订单已经退款成功");
            }
            //查询退款id
            OrderStr orderStr = orderStrDao.getOrderStr(orderid);
            tkOrderId = orderStr.getTkstrorderid();
            money = String.valueOf(((Nongsukeallid) order).getPrice());
        } else {
            return new Result(Code.POST_ERR, "没有匹配的类型");
        }
        System.out.println("money:" + money);
        //封装请求数据
        Map<String, String> tk = new HashMap<String, String>();
        tk.put("appid", weiXinPay.getAppid());
        tk.put("mch_id", weiXinPay.getMchid());
        //随机字符串
        tk.put("nonce_str", MD5Utils.randomStr());
        //退款订单id
        tk.put("out_trade_no", tkOrderId);
        //退款id
        tk.put("out_refund_no", tkOrderId);
        //订单金额，转换为分
        tk.put("total_fee", WxPayUtils.getMoney(money));
        //退款金额
        tk.put("refund_fee", WxPayUtils.getMoney(money));
        //签名
        String postStr = WxPayUtils.Md5Sgin(tk, weiXinPay.getAppsecret());
        tk.put("sign", postStr);
        String str = WxPayUtils.sendPost(tk);
        System.out.println(str);
        int rest = wxsl.wxTk(weiXinPay.getTkurl(), str);
        if (rest == 1) {
            int falge = 0;
            //更新数据
            if (type == 1) {
                falge = buyorderService.updateOrderRefund(orderid);
            } else if (type == 2) {
                falge = sendorderService.updateOrderRefund(orderid);
            } else if (type == 3) {
                falge = workorderService.updateOrderRefund(orderid);
            } else if (type == 4) {
                falge = needService.updateOrderRefund(orderid);
            } else if (type == 5) {
                falge = tzmarketService.buyUserRefund(orderid);
            }else if(type == 6){
                falge = nongsukeallidService.updateOrderRefund(orderid);
            }
            if (falge == 1) {
                return new Result(Code.POST_OK, "退款成功");
            }
            return new Result(Code.POST_ERR, "退款失败");

        }
        System.out.println("其他情况" + rest);
        return new Result(Code.POST_ERR, "退款失败");
    }

    /**
     * 退款信息查询
     *
     * @param orderid
     * @return
     */
    @GetMapping("/tkinfo/{orderid}")
    public Result gettkInfo(@PathVariable String orderid) throws Exception {
        int s = gettkOrderId(orderid);
        if (s == 1) {
            return new Result(Code.GET_OK, "订单退款成功");
        }
        return new Result(Code.GET_ERR, s, "退款失败，请联系客服");
    }

    /**
     * 根据订单号查询退款情况，方便本类调用
     *
     * @param orderid
     * @return
     */
    public int gettkOrderId(String orderid) throws Exception {
        Map<String, String> tkinfo = new HashMap<String, String>();
        tkinfo.put("appid", weiXinPay.getAppid());
        tkinfo.put("mch_id", weiXinPay.getMchid());
        //随机字符串
        tkinfo.put("nonce_str", MD5Utils.randomStr());
        //退款订单id
        tkinfo.put("out_trade_no", orderid);
        //退款id
        tkinfo.put("out_refund_no", orderid);
        //签名
        String postStr = WxPayUtils.Md5Sgin(tkinfo, weiXinPay.getAppsecret());
        tkinfo.put("sign", postStr);
        //转换成xml
        String str = WxPayUtils.sendPost(tkinfo);
        //发送查询请求
        int s = wxsl.wxtyCx(weiXinPay.getTucxurl(), str);
        return s;
    }
}
